#ifndef ANALYTEDATABASE_H
#define ANALYTEDATABASE_H

#include <QHash>
#include <QString>
#include <QList>
#include <QPair>
#include <QStringList>
#include <QDateTime>
#include<QDataStream>
#include<QColor>

#include<QDebug>

union BYTE
{
    uchar byte;
    struct
    {
        unsigned bit1 : 1;
        unsigned bit2 : 1;
        unsigned bit3 : 1;
        unsigned bit4 : 1;
        unsigned bit5 : 1;
        unsigned bit6 : 1;
        unsigned bit7 : 1;
        unsigned bit8 : 1;
    };
};

class EleAttributeBase
{
public:
    EleAttributeBase(QString name="",double massNum=1,double abundance=1);

    friend QDataStream & operator<< ( QDataStream & stream, const EleAttributeBase & eleAttributeBase )
    {
        stream<<eleAttributeBase.name
                <<eleAttributeBase.massNum
                <<eleAttributeBase.abundance
                <<eleAttributeBase.formula
                <<eleAttributeBase.interferRef
                <<eleAttributeBase.bIsUsed
                <<eleAttributeBase.bIsDefault
                <<eleAttributeBase.bIsChoose
                <<eleAttributeBase.bIsForbid;
        return stream;
    }

    friend QDataStream &	operator>> ( QDataStream & stream, EleAttributeBase & eleAttributeBase )
    {
        stream>>eleAttributeBase.name
                >>eleAttributeBase.massNum
                >>eleAttributeBase.abundance
                >>eleAttributeBase.formula
                >>eleAttributeBase.interferRef
                >>eleAttributeBase.bIsUsed
                >>eleAttributeBase.bIsDefault
                >>eleAttributeBase.bIsChoose
                >>eleAttributeBase.bIsForbid;
        return stream;
    }
     EleAttributeBase &	operator= ( const EleAttributeBase & eleAttributeBase )
    {
        this->name=eleAttributeBase.name;
        this->massNum=eleAttributeBase.massNum;
        this->abundance=eleAttributeBase.abundance;
        this->formula=eleAttributeBase.formula;
        this->interferRef=eleAttributeBase.interferRef;
        this->bIsUsed=eleAttributeBase.bIsUsed;
        this->bIsDefault=eleAttributeBase.bIsDefault;
        this->bIsChoose=eleAttributeBase.bIsChoose;
        this->bIsForbid=eleAttributeBase.bIsForbid;

        return *this;
    }

//private:
    int nucleus;//原子核

    QString name;//名称（质量数+元素）：质量数取整
    double massNum;//质量数
    double abundance;//丰度
    QString formula;//方程式
    QString interferRef;//干扰参考
    bool bIsUsed;//true:实验调用界面使能 出现
    bool bIsDefault;//?
    bool bIsChoose;//非谱线界面使用,选中构建其他元素关联表
    bool bIsForbid;   
};

class EleAttributes
{
public:
    EleAttributes();
    QHash<QString,EleAttributeBase> GetEleAttributes();
    void InsertElement(QString,EleAttributeBase);
    void RemoveElement(QString,EleAttributeBase);
    void SetElement(QString,EleAttributeBase);
    void SetRsf(double value);
    void SetAtomicNum(double value);
    void SetEnergyFirst(double value);
    void SetEnergySecond(double value);

    friend QDataStream & operator<< ( QDataStream & stream, const EleAttributes & eleAttributes )
    {
        stream<<eleAttributes.datas
                <<eleAttributes.name
                <<eleAttributes.atomicNum
                <<eleAttributes.rsf
                <<eleAttributes.energyFirst
                <<eleAttributes.energySecond;
        return stream;
    }

    friend QDataStream &	operator>> ( QDataStream & stream, EleAttributes & eleAttributes )
    {
        stream>>eleAttributes.datas
                >>eleAttributes.name
                >>eleAttributes.atomicNum
                >>eleAttributes.rsf
                >>eleAttributes.energyFirst
                >>eleAttributes.energySecond;
        return stream;
    }

//private:
    //QList<EleAttributeBase> datas;
    QHash<QString,EleAttributeBase> datas;
    QString name;//Li
    int atomicNum;//原子序数
    double rsf;
    double energyFirst;
    double energySecond;

    //other
    double meltingPoint;
    double boilingPoint;
    QString other;
};

class AnalyteDataBase
{
public:
    AnalyteDataBase();

    QHash<QString,EleAttributes> GetElements(int type);//
    QHash<QString,EleAttributes> GetElementTable();
    QHash<QString,EleAttributes> GetElementMutiTable();
    QHash<QString,EleAttributes> GetElementBaseTable();
    QHash<QString,EleAttributes> GetAnalyteDatas();
    QList<QPair<double,double> > GetForbidRangs();
    QList<QPair<double,double> > GetEnableRangs();
    double GetElementMass(QString);

    QStringList GetAnalyteElements();//更新带分析元素表（3张表元素各不同）
    QMap<double,QString> GetAnalyteElementPairs();

    void InsertEleAttributes(EleAttributes attribute,QString element,int type);//元素
    void RemoveEleAttributes(EleAttributes attribute,QString element,int type);
    void SetEleAttributes(EleAttributes attribute,QString positon,int type);
    void InsertEleAttribute(QString massElement,EleAttributeBase isotope,QString element,int type);//同位素
    void RemoveEleAttribute(QString massElement,EleAttributeBase isotope,QString element,int type);
    void SetEleAttribute(QString massElement,EleAttributeBase isotope,QString element,int type);
    void SetEleRsf(double rsf,QString element,int type);//设置rsf
    void SetEleAtomicNum(double atomicNum,QString element,int type);//设置atomicNum
    void SetEleEnergyFirst(double energyFirst,QString element,int type);//设置energyFirst
    void SetEleEnergySecond(double energySecond,QString element,int type);//设置energySecond

    friend QDataStream & operator<< ( QDataStream & stream, const AnalyteDataBase & analyteDataBase )
    {
        stream<<analyteDataBase.elementTable
                <<analyteDataBase.elementMutiTable
                <<analyteDataBase.elementBaseTable
                <<analyteDataBase.forbidRangs;
        return stream;
    }

    friend QDataStream &	operator>> ( QDataStream & stream, AnalyteDataBase & analyteDataBase )
    {
        stream>>analyteDataBase.elementTable
                >>analyteDataBase.elementMutiTable
                >>analyteDataBase.elementBaseTable
                >>analyteDataBase.forbidRangs;
        return stream;
    }
private:
    void Init();

    //元素不同可合并成一张表
    QHash<QString,EleAttributes> elementTable;//QString:元素名称 不变
    QHash<QString,EleAttributes> elementMutiTable;//可变
    QHash<QString,EleAttributes> elementBaseTable;//可变

    QList<QPair<double,double> > forbidRangs;
    QList<QPair<double,double> > enableRangs;//与forbidRangs反

    QStringList elementList;//默认元素
    QStringList elementBaseList;//
    QStringList elementMutiList;//

    QHash<QString,EleAttributes> analyteDatas;//bIsChoose=true

    int type;//type=0:elementTable 1:elementMutiTable 2:elementBaseTable
};


//
typedef union _SystemState
{
    int state;
    struct
    {
        unsigned START_STOP : 1;
        unsigned  :7 ;
        unsigned  READY: 2;
        unsigned  :6 ;

        unsigned  : 8;
        unsigned  : 8;
    };
}SystemState;
//
struct CalRatio
{  
    CalRatio();
    friend QDataStream & operator<< ( QDataStream & stream, const CalRatio & calRatio )
    {
        stream<<calRatio.name
              <<calRatio.dateTime
              <<calRatio.ratios;
        return stream;
    }

    friend QDataStream &	operator>> ( QDataStream & stream, CalRatio & calRatio )
    {
        stream>>calRatio.name
              >>calRatio.dateTime
              >>calRatio.ratios;
        return stream;
    }

    QString name;
    QDateTime dateTime;
    QList<double> ratios;//0:常数 1-4：函数次数
};

//tuneManual
struct HopScanParaManual
{
    HopScanParaManual()
    {
        massNum=0;

        name="";//名称（质量数+元素）：质量数取整
        dwelltime=10;
        chanels=3;
        interval=0.01;
        type="标准";

        //add
        bIsUsed=false;
        bIsDisplay=false;
        //QColor color;

        data=0;
        dataRsd=0;
    }

    friend QDataStream & operator<< ( QDataStream & stream, const HopScanParaManual & hopScanPara )
    {
        stream<<hopScanPara.name
                <<hopScanPara.dwelltime
                <<hopScanPara.chanels
                <<hopScanPara.interval
                <<hopScanPara.type
                <<hopScanPara.massNum
                <<hopScanPara.data
                <<hopScanPara.dataRsd;
        return stream;
    }

    friend QDataStream &	operator>> ( QDataStream & stream, HopScanParaManual & hopScanPara )
    {
        stream>>hopScanPara.name
                >>hopScanPara.dwelltime
                >>hopScanPara.chanels
                >>hopScanPara.interval
                >>hopScanPara.type
                >>hopScanPara.massNum
                >>hopScanPara.data
                >>hopScanPara.dataRsd;
        return stream;
    }

    double massNum;

    QString name;//名称（质量数+元素）：质量数取整
    double dwelltime;
    int chanels;
    double interval;
    QString type;

    //add
    bool bIsUsed;
    bool bIsDisplay;
    QColor color;

    double data;
    double dataRsd;

};
struct SweepScanParaManual
{
    SweepScanParaManual()
    {
        startMassNum=0;
        endMassNum=0;
        dwelltime=1;
        channelsAmu=11;
        type="标准";
        //add
        bIsUsed=false;
        bIsDisplay=false;
        //QColor color;
    }
    //void SetStartEnd(double start,double end);

    friend QDataStream & operator<< ( QDataStream & stream, const SweepScanParaManual & sweepScanPara )
    {
        stream<<sweepScanPara.startMassNum
                <<sweepScanPara.endMassNum
                <<sweepScanPara.dwelltime
                <<sweepScanPara.channelsAmu
                <<sweepScanPara.type
                <<sweepScanPara.bIsUsed
                <<sweepScanPara.bIsDisplay
                <<sweepScanPara.color;
        return stream;
    }

    friend QDataStream &	operator>> ( QDataStream & stream, SweepScanParaManual & sweepScanPara )
    {
        stream>>sweepScanPara.startMassNum
                >>sweepScanPara.endMassNum
                >>sweepScanPara.dwelltime
                >>sweepScanPara.channelsAmu
                >>sweepScanPara.type
                >>sweepScanPara.bIsUsed
                >>sweepScanPara.bIsDisplay
                >>sweepScanPara.color;
        return stream;
    }

    double startMassNum;
    double endMassNum;
    double dwelltime;
    int channelsAmu;
    QString type;

    //add
    bool bIsUsed;
    bool bIsDisplay;
    QColor color;
};
//段扫描 界面有问题
struct SweepScanPara
{
    SweepScanPara();
    void SetStartEnd(double start,double end);
    bool CheckValid();

    friend QDataStream & operator<< ( QDataStream & stream, const SweepScanPara & sweepScanPara )
    {
        stream<<sweepScanPara.startMassNum
                <<sweepScanPara.endMassNum
                <<sweepScanPara.dwelltime
                <<sweepScanPara.channelsAmu
                <<sweepScanPara.type
                <<sweepScanPara.bIsUsed
                <<sweepScanPara.bIsDisplay
                <<sweepScanPara.color
                <<sweepScanPara.name;
        return stream;
    }

    friend QDataStream &	operator>> ( QDataStream & stream, SweepScanPara & sweepScanPara )
    {
        stream>>sweepScanPara.startMassNum
                >>sweepScanPara.endMassNum
                >>sweepScanPara.dwelltime
                >>sweepScanPara.channelsAmu
                >>sweepScanPara.type
                >>sweepScanPara.bIsUsed
                >>sweepScanPara.bIsDisplay
                >>sweepScanPara.color
                >>sweepScanPara.name;
        return stream;
    }

    double startMassNum;
    double endMassNum;
    double dwelltime;
    int channelsAmu;
    QString type;

    //add
    bool bIsUsed;
    bool bIsDisplay;
    QColor color;
    QString name;//主扫描用
};
//跳峰扫描
struct HopScanPara
{
    HopScanPara();
    bool CheckValid();

    friend QDataStream & operator<< ( QDataStream & stream, const HopScanPara & hopScanPara )
    {
        stream<<hopScanPara.name
                <<hopScanPara.dwelltime
                <<hopScanPara.chanels
                <<hopScanPara.interval
                <<hopScanPara.type
                <<hopScanPara.massNum
                <<hopScanPara.bIsUsed
                <<hopScanPara.bIsDisplay
                <<hopScanPara.color
                <<hopScanPara.data
                <<hopScanPara.dataRsd;
        return stream;
    }

    friend QDataStream &	operator>> ( QDataStream & stream, HopScanPara & hopScanPara )
    {
        stream>>hopScanPara.name
                >>hopScanPara.dwelltime
                >>hopScanPara.chanels
                >>hopScanPara.interval
                >>hopScanPara.type
                >>hopScanPara.massNum
                >>hopScanPara.bIsUsed
                >>hopScanPara.bIsDisplay
                >>hopScanPara.color
                >>hopScanPara.data
                >>hopScanPara.dataRsd;
        return stream;
    }

    double massNum;

    QString name;//名称（质量数+元素）：质量数取整
    double dwelltime;
    int chanels;
    double interval;
    QString type;

    //add
    bool bIsUsed;
    bool bIsDisplay;
    QColor color;

    double data;
    double dataRsd;
};
struct ScanPara //temp
{
    QString name;

    double startMassNum;
    double endMassNum;
    double dwelltime;
    double interval;
    int channels;//
    QString type;

    //add
    bool bIsUsed;
    bool bIsDisplay;
    QColor color;

 //   double data;
 //   double dataRsd;
};

struct ExpConllectPara//
{
    ExpConllectPara();

    bool EnablePreScan(bool state);
    bool IsPreScan();

    bool SetPreScanCount(int count);
    int GetPreScanCount();

    double GetPreScanTime();

    QList<SweepScanPara> GetPreSweepScanParas();
    SweepScanPara GetPreSweepScanPara(int index);
    void SetPreSweepScanPara(int,SweepScanPara);
    void SetPreSweepScanParas(QList<SweepScanPara>);
    void InitPreScanPara(QList<QPair<double,double> >);

    bool EnableScan(bool state);
    bool IsScan();


    bool SetScanCount(int count);
    int GetScanCount();

    double GetScanTime();

    QHash<QString,SweepScanPara> GetSweepScanParas();
    SweepScanPara GetSweepScanPara(QString index);
    bool SetSweepScanParas(QHash<QString,SweepScanPara> paras);
    bool SetSweepScanPara(QString index,SweepScanPara sweepScanPara);
    bool RemoveSweepScanPara(QString index);
    bool AddSweepScanPara(QString index,SweepScanPara sweepScanPara);

    QHash<QString,HopScanPara> GetHopScanParas();
    HopScanPara GetHopScanPara(QString);
    bool SetHopScanPara(QString name,HopScanPara hopScanPara);
    bool AddHopScanPara(QString,HopScanPara);
    bool RemoveHopScanPara(QString name);

    friend QDataStream & operator<< ( QDataStream & stream, const ExpConllectPara & expConllectPara )
    {
        stream<<expConllectPara.bPreScan
                <<expConllectPara.preScanCount
                <<expConllectPara.preSweepScanParas
                <<expConllectPara.bScan
                <<expConllectPara.scanCount
                <<expConllectPara.sweepScanParas
                <<expConllectPara.hopScanParas;
        return stream;
    }

    friend QDataStream &	operator>> ( QDataStream & stream, ExpConllectPara & expConllectPara )
    {
        stream>>expConllectPara.bPreScan
                >>expConllectPara.preScanCount
                >>expConllectPara.preSweepScanParas
                >>expConllectPara.bScan
                >>expConllectPara.scanCount
                >>expConllectPara.sweepScanParas
                >>expConllectPara.hopScanParas;
        return stream;
    }

  bool bPreScan;
  int preScanCount;
  double preScanTime;
  QList<SweepScanPara> preSweepScanParas;

  bool bScan;//0:跳峰扫描 1:段扫描
  int scanCount;
  double mainScanTime;
  QHash<QString,SweepScanPara> sweepScanParas;//
  QHash<QString,HopScanPara> hopScanParas;//
};
//
struct TuneResult
{
    TuneResult()
    {
        bIsChoose=false;
        creatTime=QDateTime::currentDateTime().toString("yyyyMMddhhmmss");
        fileName="test";//索引目录文件用
        info="";
        powerRf=0;//
        atomization=0;//
        auxiliary=0;//
        cooler=0;//
        added=0;//
        collisionGasH2=0;//
        collisionGasHe=0;//
        extractionLen=0;//
        hexapole=0;//
        len1=0;//
        len2=0;//
        len3=0;//
        focusingLen=0;//
        deflectionLen1=0;//
        deflectionLen2=0;//
        deflectionLen3=0;//
        deflectionLen4=0;//
        quadrupole=0;//
        analogDetector=0;//
        digitalDetector=0;//
        detectorGate=0;
        motorX=0;
        motorY=0;//
        motorZ=0;//
    }

    friend QDataStream & operator<< ( QDataStream & stream, const TuneResult & tuneResult )
    {
        stream<<tuneResult.bIsChoose
               <<tuneResult.creatTime
               <<tuneResult.fileName
               <<tuneResult.info
               <<tuneResult.powerRf
               <<tuneResult.atomization
               <<tuneResult.auxiliary
               <<tuneResult.cooler
               <<tuneResult.added
               <<tuneResult.collisionGasH2
               <<tuneResult.collisionGasHe
               <<tuneResult.extractionLen
               <<tuneResult.hexapole
               <<tuneResult.len1
               <<tuneResult.len2
               <<tuneResult.len3
               <<tuneResult.focusingLen
               <<tuneResult.deflectionLen1
               <<tuneResult.deflectionLen2
               <<tuneResult.deflectionLen3
               <<tuneResult.deflectionLen4
               <<tuneResult.quadrupole
               <<tuneResult.analogDetector
               <<tuneResult.digitalDetector
               <<tuneResult.detectorGate
               <<tuneResult.motorX
               <<tuneResult.motorY
               <<tuneResult.motorZ;
        return stream;
    }

    friend QDataStream &	operator>> ( QDataStream & stream, TuneResult & tuneResult )
    {
        stream>>tuneResult.bIsChoose
               >>tuneResult.creatTime
               >>tuneResult.fileName
               >>tuneResult.info
               >>tuneResult.powerRf
               >>tuneResult.atomization
               >>tuneResult.auxiliary
               >>tuneResult.cooler
               >>tuneResult.added
               >>tuneResult.collisionGasH2
               >>tuneResult.collisionGasHe
               >>tuneResult.extractionLen
               >>tuneResult.hexapole
               >>tuneResult.len1
               >>tuneResult.len2
               >>tuneResult.len3
               >>tuneResult.focusingLen
               >>tuneResult.deflectionLen1
               >>tuneResult.deflectionLen2
               >>tuneResult.deflectionLen3
               >>tuneResult.deflectionLen4
               >>tuneResult.quadrupole
               >>tuneResult.analogDetector
               >>tuneResult.digitalDetector
               >>tuneResult.detectorGate
               >>tuneResult.motorX
               >>tuneResult.motorY
               >>tuneResult.motorZ;
        return stream;
    }

    bool bIsChoose;
    QString creatTime;
    QString fileName;//索引目录文件用
    QString info;
    double powerRf;//功率
    double atomization;//雾化气
    double auxiliary;//辅助气
    double cooler;//冷却气
    double added;//附加气
    double collisionGasH2;//碰撞气H2
    double collisionGasHe;//碰撞气He
    double extractionLen;//提取透镜
    double hexapole;//六级杆
    double len1;//透镜1
    double len2;//透镜2
    double len3;//透镜3
    double focusingLen;//聚焦透镜
    double deflectionLen1;//偏转透镜1
    double deflectionLen2;//偏转透镜2
    double deflectionLen3;//偏转透镜3
    double deflectionLen4;//偏转透镜4
    double quadrupole;//四级杆
    double analogDetector;//模拟检测器
    double digitalDetector;//计数检测器
    double detectorGate;//检测器Gate
    double motorX;//
    double motorY;//
    double motorZ;//
};

//
struct ExtractionMonitorList
{
    friend QDataStream & operator<< ( QDataStream & stream, const ExtractionMonitorList & extractionMonitorList )
    {
        stream<<extractionMonitorList.massNum
                <<extractionMonitorList.dwelltime
                <<extractionMonitorList.channels
                <<extractionMonitorList.interval
                <<extractionMonitorList.greaterThan
                <<extractionMonitorList.lessThan
                <<extractionMonitorList.type;
        return stream;
    }

    friend QDataStream &	operator>> ( QDataStream & stream, ExtractionMonitorList & extractionMonitorList )
    {
        stream>>extractionMonitorList.massNum
                >>extractionMonitorList.dwelltime
                >>extractionMonitorList.channels
                >>extractionMonitorList.interval
                >>extractionMonitorList.greaterThan
                >>extractionMonitorList.lessThan
                >>extractionMonitorList.type;
        return stream;
    }

  double massNum;
  int dwelltime;
  int channels;
  double interval;
  int greaterThan;//ICPS
  int lessThan;//稳定性 ICPS
  QString type;//标准 高标
};
struct ExtractionTime
{
    ExtractionTime()
    {
        expBefore=0;//
        expAfter=0;//

        extractMinDelay=2;
        extractMaxDelay=30;
        extractDelayAction="继续";
        extractStabilityTime=0;
        bExtractMonitor=false;
        extractMean=1;
        //extractList;

        washMinDelay=2;
        washMaxDelay=30;
        washDelayAction="继续";
        bWashMonitor=false;
        washMean=1;
        washPumpSpeed=30;
        washStabilityTime=5;
        //washList;

        bInjectorUsed=false;
        injectorPumpSpeed=200;
    }
    friend QDataStream & operator<< ( QDataStream & stream, const ExtractionTime & extractionTime )
    {
        //qDebug()<<"extractionTime.expBefore11"<<extractionTime.expBefore;
        stream<<extractionTime.expBefore
                <<extractionTime.expAfter
                <<extractionTime.extractMinDelay
                <<extractionTime.extractMaxDelay
                <<extractionTime.extractDelayAction
                <<extractionTime.extractStabilityTime
                <<extractionTime.bExtractMonitor
                <<extractionTime.extractMean
                <<extractionTime.extractList
                <<extractionTime.washMinDelay
                <<extractionTime.washMaxDelay
                <<extractionTime.washDelayAction
                <<extractionTime.bWashMonitor
                <<extractionTime.washMean
                <<extractionTime.washPumpSpeed
                <<extractionTime.washStabilityTime
                <<extractionTime.washList
                <<extractionTime.bInjectorUsed
                <<extractionTime.injectorPumpSpeed;
        return stream;
    }

    friend QDataStream &	operator>> ( QDataStream & stream, ExtractionTime & extractionTime )
    {
        stream>>extractionTime.expBefore
                >>extractionTime.expAfter
                >>extractionTime.extractMinDelay
                >>extractionTime.extractMaxDelay
                >>extractionTime.extractDelayAction
                >>extractionTime.extractStabilityTime
                >>extractionTime.bExtractMonitor
                >>extractionTime.extractMean
                >>extractionTime.extractList
                >>extractionTime.washMinDelay
                >>extractionTime.washMaxDelay
                >>extractionTime.washDelayAction
                >>extractionTime.bWashMonitor
                >>extractionTime.washMean
                >>extractionTime.washPumpSpeed
                >>extractionTime.washStabilityTime
                >>extractionTime.washList
                >>extractionTime.bInjectorUsed
                >>extractionTime.injectorPumpSpeed;
        //qDebug()<<"extractionTime.expBefore12"<<extractionTime.expBefore;
        return stream;
    }

   int expBefore;//
   int expAfter;//

   int extractMinDelay;
   int extractMaxDelay;
   QString extractDelayAction;
   int extractStabilityTime;
   bool bExtractMonitor;
   int  extractMean;
   ExtractionMonitorList extractList;

   int washMinDelay;
   int washMaxDelay;
   QString washDelayAction;
   bool bWashMonitor;
   int washMean;
   int washPumpSpeed;
   int washStabilityTime;
   ExtractionMonitorList washList;

   bool bInjectorUsed;
   int injectorPumpSpeed;
};

//同位素
struct IsotopePara
{
    QList<QPair<QString,QString> > GetIsotopePara()
    {
        return isotopeRatios;
    }
    bool AddIsotope(QPair<QString,QString> pair)
    {
        if(isotopeRatios.contains(pair)) return false;
        isotopeRatios.append(pair);
        return true;
    }
    bool DeleteIsotope(QPair<QString,QString> pair)
    {
        isotopeRatios.removeOne(pair);
        return true;
    }

    friend QDataStream & operator<< ( QDataStream & stream, const IsotopePara & isotopePara )
    {
        stream<<isotopePara.isotopeRatios;
        return stream;
    }

    friend QDataStream &	operator>> ( QDataStream & stream, IsotopePara & isotopePara )
    {
        stream>>isotopePara.isotopeRatios;
        return stream;
    }

    QList<QPair<QString,QString> > isotopeRatios;
};

//内标参数
struct InternalPara
{
    InternalPara()
    {
        type=false;
        internalS="无";
        concentration=0;
        unit="ppb";
    }
    friend QDataStream & operator<< ( QDataStream & stream, const InternalPara & internalPara )
    {
        stream<<internalPara.type
                <<internalPara.internalS
                <<internalPara.concentration
                <<internalPara.unit;
        return stream;
    }

    friend QDataStream &	operator>> ( QDataStream & stream, InternalPara & internalPara )
    {
        stream>>internalPara.type
                >>internalPara.internalS
                >>internalPara.concentration
                >>internalPara.unit;
        return stream;
    }
    bool type;//0:普通 1：设为内标
    QString internalS;//内标(无、插值、其他内标元素)
    double concentration;//浓度
    QString unit;//浓度单位()
};

//定量参数
struct QuantitativeParaCal
{
    QString sampleName;//sample
    double cnRef;
    double cn;//
    double cpsMean;
    double error;
    double rError;
    QList<double> cpss;
    bool bIsUsed;
};

struct QuantitativePara
{
    QuantitativePara()
    {
        quantitativeMethod="无";
        functionCount="一次函数";
        weight="无";
        bIsHalf=false;
        limit=0;
        unit="ppb";

        for(int i=0;i<5;i++)
        {
            ratios.append(0);
        }
    }
    void SetFunctionCount(QString name)
    {
        functionCount=name;
    }
    QString GetFunctionCount()
    {
        return functionCount;
    }
    void SetWeight(QString name)
    {
       weight=name;
    }
    QString GetWeight()
    {
        return weight;
    }
    void SetRatios(QList<double> datas)
    {
        ratios=datas;
    }
    QList<double> GetRatios()
    {
        return ratios;
    }
    double GetCn(double x)
    {
        double y=0;
        int count=ratios.count();
        for(int i=0;i<count;i++)
        {
           switch(i)
           {
           case 0:
               y+=ratios.at(0);
               break;
           case 1:
               y+=ratios.at(1)*x;
               break;
           case 2:
               y+=ratios.at(2)*x*x;
               break;
           case 3:
               y+=ratios.at(3)*x*x*x;
               break;
           case 4:
               y+=ratios.at(4)*x*x*x*x;
               break;
           }
        }
        return y;
    }
    QList<QuantitativeParaCal> GetCalDatas()
    {
        return datas;
    }
    void SetCalDatas(QList<QuantitativeParaCal> values)
    {
        datas=values;
    }
    void SetUint(QString name)
    {
        unit=name;
    }
    QString GetUnit()
    {
        return unit;
    }

    friend QDataStream & operator<< ( QDataStream & stream, const QuantitativePara & quantitativePara )
    {
        stream<<quantitativePara.quantitativeMethod
                <<quantitativePara.functionCount
                <<quantitativePara.weight
                <<quantitativePara.bIsHalf
                <<quantitativePara.limit;
        return stream;
    }

    friend QDataStream &	operator>> ( QDataStream & stream, QuantitativePara & quantitativePara )
    {
        stream>>quantitativePara.quantitativeMethod
                >>quantitativePara.functionCount
                >>quantitativePara.weight
                >>quantitativePara.bIsHalf
                >>quantitativePara.limit;
        return stream;
    }
    QString quantitativeMethod;//(无、全定量、标准加入)
    QString functionCount;//(一次函数、二次函数)
    QString weight;//（无、1/SD、1/浓度、过原点） 标准加入:无、1/SD、过标准加入零点
    bool bIsHalf;
    double limit;

    //(全定量、标准加入)
    QString unit;
    QList<QuantitativeParaCal> datas;
    QList<double> ratios;//
};

//QC参数
struct QcPara
{
    friend QDataStream & operator<< ( QDataStream & stream, const QcPara & qcPara )
    {
        return stream;
    }

    friend QDataStream &	operator>> ( QDataStream & stream, QcPara & qcPara )
    {
        return stream;
    }
    int save;//
};

//元素相关的表
struct EleMethod
{
public:
    //EleMethod();
    void InitStartEnd(double value,double start,double end)
    {
        sweepScanPara.startMassNum=start;
        sweepScanPara.endMassNum=end;

        hopScanPara.massNum=value;
    }
    QuantitativePara* GetQuantitativeParaPtr()
    {
        return &quantitativePara;
    }
    InternalPara* GetInternalParaPtr()
    {
        return &internalPara;
    }

    friend QDataStream & operator<< ( QDataStream & stream,  const EleMethod & eleMethod )
    {
        stream<<eleMethod.internalPara
                <<eleMethod.hopScanPara
                <<eleMethod.sweepScanPara
                <<eleMethod.quantitativePara
                <<eleMethod.qcPara;
        return stream;
    }

    friend QDataStream &	operator>> ( QDataStream & stream, EleMethod & eleMethod )
    {
        stream>>eleMethod.internalPara
                >>eleMethod.hopScanPara
                >>eleMethod.sweepScanPara
                >>eleMethod.quantitativePara
                >>eleMethod.qcPara;
        return stream;
    }

//private:
    //跳峰扫描
    HopScanPara hopScanPara;//
    //段扫描
    SweepScanPara sweepScanPara;//

    //内标
    InternalPara internalPara;
    //定量方法
    QuantitativePara quantitativePara;
    //QC
    QcPara qcPara;//内标无质控 
};

struct ExpMethod
{
    void InitMethod(AnalyteDataBase *);
    bool SetMethod(QString,EleMethod);
    EleMethod GetEleMethod(QString);
    EleMethod *GetEleMethodPtr(QString);
    QHash<QString,EleMethod> GetMethods();

    friend QDataStream & operator<< ( QDataStream & stream,  const ExpMethod & method )
    {
        stream<<method.eleMethods;
        return stream;
    }

    friend QDataStream &	operator>> ( QDataStream & stream, ExpMethod & method )
    {
        stream>>method.eleMethods;
        return stream;
    }

    QHash<QString,EleMethod> eleMethods;

};

struct ExpRawData
{
    friend QDataStream & operator<< ( QDataStream & stream, const ExpRawData & expRawData )
    {
        stream<<expRawData.plusedValue
                <<expRawData.analogValue
                <<expRawData.sweepCount;
        return stream;
    }

    friend QDataStream &	operator>> ( QDataStream & stream, ExpRawData & expRawData )
    {
        stream>>expRawData.plusedValue
                >>expRawData.analogValue
                >>expRawData.sweepCount;
        return stream;
    }

   // QList<double> datas;//原始数据

    //结果表
    double plusedValue;
    double analogValue;
    int sweepCount;
};

//other
union SwitchValue
{
    uint value;
    struct
    {
        unsigned collisionGas1 : 1;//开关量：第1碰撞气电磁阀
        unsigned collisionGas2 : 1;
        unsigned  : 1;//3
        unsigned vacuumGauge : 1;//开关量：高真空规开关
        unsigned mechanicPump1 : 1;//开关量：机械泵继电器1（机械泵）
        unsigned  : 1;//2
        unsigned angleValve : 1;//开关量：角阀
        unsigned frontValve : 1;//开关量：backing阀（前级阀）

        unsigned ventValve : 1;//开关量：放空阀
        unsigned turboVent : 1;//开关量：分子泵放空阀
        unsigned turboPump : 1;//开关量：分子泵（1为打开）
        unsigned coolGas : 1;//开关量：滑动阀开关
        unsigned coolWarter : 1;//开关量：水路电磁阀1
        unsigned argonWhole: 1;//开关量：氩气总电磁阀（高级）
        unsigned peristalticPumpD : 1;//1bite：蠕动泵方向
        unsigned onRf: 1;//开关量：ICP源RF功率 ON/OFF(1为one)

        unsigned depthTrigger : 1;//开关量1bite：深度触发开关
        unsigned sampleConeT : 1;//开关量：采样锥温度开关
        unsigned torch1 : 1;//开关量：炬室门开关
        unsigned  : 1;//2
        unsigned flame: 1;//开关量：火焰光纤开关信号
        unsigned wasterDetection: 1;//开关量：废液检测异常信号
        unsigned  argonPressure: 1;//开关量：氩气压力开关
        unsigned  : 1;//icp

        unsigned  : 8;
    };
};

struct WorkStepCondition
{
    WorkStepCondition()
    {
        bIsChoose=false;
        index=0;//对应符号
        value=0;
    }

    friend QDataStream & operator<< ( QDataStream & stream, const WorkStepCondition & workStepCondition )
    {
        stream<<workStepCondition.bIsChoose
                <<workStepCondition.index
                <<workStepCondition.value;
        return stream;
    }

    friend QDataStream &	operator>> ( QDataStream & stream, WorkStepCondition & workStepCondition )
    {
        stream>>workStepCondition.bIsChoose
                >>workStepCondition.index
                >>workStepCondition.value;
        return stream;
    }

    bool bIsChoose;
    int index;//对应符号
    double value;
};

struct WorkStep //可按需添加其他变量
{
    WorkStep()
    {
        id=0;//
        name="step1";//
        WorkStepCondition condition;
        conditions.append(condition);
        conditions.append(condition);
        conditions.append(condition);
        conditions.append(condition);
        conditions.append(condition);
        conditions.append(condition);
        conditions.append(condition);
        instrumentState="真空";//
        runningInfor="进行中";//
        runningDelay=2;
        finishedInfor="完成";//
        finishedDelay=2;///
        timeOut=10;//
        exceptFlowName="";

        plasmaOnOff="关闭";//等离子气开关
        cooler=0;//冷却气
        auxiliary=0;//辅助气
        atomization=0;//雾化气
        added=0;//附加气
        coolWarterOnOff="关闭";//冷却水开关
        coolGasOnOff="关闭";//滑动阀开关
        coolwarter=0;//冷却水
        atomizationT=20;//雾化气T
        peristalticPumpD="顺时针";//蠕动泵方向
        peristalticPumpSpeed=0;//蠕动泵转速
        powerRf=0;//RF功率
        voltageRfOnOff="关闭";//RF高压
        restoreRfOnOff="关闭";//RF复位
        onRfOnOff="关闭";//RFON
        motorZ=0;//
        motorX=0;//
        motorY=0;//
        groundOnOff="关闭";//接地开关
        readyLedOnOff="关闭";//ReadyLed
        mechanicPumpOnOff="关闭";//机械泵
        turboPumpOnOff="关闭";//分子泵
        vacuumGaugeOnOff="关闭";//高真空规
        frontValveOnOff="关闭";//前级阀
        angleValveOnOff="关闭";//角阀
        ventValveOnOff="关闭";//放空阀
        turboVentOnOff="关闭";//分子泵放空阀
        collisionGas1OnOff="关闭";//碰撞气1开关
        collisionGasHe=0;//碰撞气1
        collisionGas2OnOff="关闭";//碰撞气开关
        collisionGasH2=0;//碰撞气2
        samplingConeT=0;//采样锥温度
        lenGroupOnOff="关闭";//透镜组电压开关
        extractionLen=0;//提取透镜
        hexapole=0;//六级杆
        len1=0;//透镜1
        len2=0;//透镜2
        len3=0;//透镜3
        focusingLen=0;//聚焦透镜
        deflectionLen1=0;//偏转透镜1
        deflectionLen2=0;//偏转透镜2
        deflectionLen3=0;//偏转透镜3
        deflectionLen4=0;//偏转透镜4
        quadrupole=0;//四级杆
        analogDetector=0;//模拟检测器
        digitalDetector=0;//计数检测器
        standardResolution=0;//模拟检测器
        highResolution=0;//计数检测器

        //add
    }

    bool IsCondition()//条件有效
    {
        foreach(WorkStepCondition condition,conditions)
        {
            if(condition.bIsChoose==true) return true;
        }
        return false;
    }

    friend QDataStream & operator<< ( QDataStream & stream, const WorkStep & workStep )
    {
        stream<<workStep.id
              <<workStep.name
              <<workStep.conditions
              <<workStep.instrumentState
              <<workStep.runningInfor
              <<workStep.runningDelay
              <<workStep.finishedInfor
              <<workStep.finishedDelay
              <<workStep.timeOut
              <<workStep.exceptFlowName
              <<workStep.cooler
              <<workStep.auxiliary
              <<workStep.atomization
              <<workStep.added
              <<workStep.coolwarter
              <<workStep.atomizationT
              <<workStep.peristalticPumpSpeed
              <<workStep.powerRf
              <<workStep.motorZ
              <<workStep.motorX
              <<workStep.motorY
              <<workStep.collisionGasHe
              <<workStep.collisionGasH2
              <<workStep.samplingConeT
              <<workStep.extractionLen
              <<workStep.hexapole
              <<workStep.len1
              <<workStep.len2
              <<workStep.len3
              <<workStep.focusingLen
              <<workStep.deflectionLen1
              <<workStep.deflectionLen2
              <<workStep.deflectionLen3
              <<workStep.deflectionLen4
              <<workStep.quadrupole
              <<workStep.analogDetector
              <<workStep.digitalDetector
              <<workStep.standardResolution
              <<workStep.highResolution
              <<workStep.switchValue.value;
        return stream;
    }

    friend QDataStream &	operator>> ( QDataStream & stream,  WorkStep & workStep )
    {
        stream>>workStep.id
              >>workStep.name
              >>workStep.conditions
              >>workStep.instrumentState
              >>workStep.runningInfor
              >>workStep.runningDelay
              >>workStep.finishedInfor
              >>workStep.finishedDelay
              >>workStep.timeOut
              >>workStep.exceptFlowName
              >>workStep.cooler
              >>workStep.auxiliary
              >>workStep.atomization
              >>workStep.added
              >>workStep.coolwarter
              >>workStep.atomizationT
              >>workStep.peristalticPumpSpeed
              >>workStep.powerRf
              >>workStep.motorZ
              >>workStep.motorX
              >>workStep.motorY
              >>workStep.collisionGasHe
              >>workStep.collisionGasH2
              >>workStep.samplingConeT
              >>workStep.extractionLen
              >>workStep.hexapole
              >>workStep.len1
              >>workStep.len2
              >>workStep.len3
              >>workStep.focusingLen
              >>workStep.deflectionLen1
              >>workStep.deflectionLen2
              >>workStep.deflectionLen3
              >>workStep.deflectionLen4
              >>workStep.quadrupole
              >>workStep.analogDetector
              >>workStep.digitalDetector
              >>workStep.standardResolution
              >>workStep.highResolution
              >>workStep.switchValue.value;
        return stream;
    }

    int id;//
    QString name;//
    QList<WorkStepCondition> conditions;//
    QString instrumentState;//
    QString runningInfor;//
    int runningDelay;
    QString finishedInfor;//
    int finishedDelay;///
    int timeOut;//
    QString exceptFlowName;

    SwitchValue switchValue;
    QString plasmaOnOff;//等离子气开关
    double cooler;//冷却气
    double auxiliary;//辅助气
    double atomization;//雾化气
    double added;//附加气
    QString coolWarterOnOff;//冷却水开关
    QString coolGasOnOff;//滑动阀开关
    double coolwarter;//冷却水
    double atomizationT;//雾化气T
    QString peristalticPumpD;//蠕动泵方向
    double peristalticPumpSpeed;//蠕动泵转速
    double powerRf;//RF功率
    QString voltageRfOnOff;//RF高压
    QString restoreRfOnOff;//RF复位
    QString onRfOnOff;//RFON
    double motorZ;//
    double motorX;//
    double motorY;//
    QString groundOnOff;//接地开关
    QString readyLedOnOff;//ReadyLed
    QString mechanicPumpOnOff;//机械泵
    QString turboPumpOnOff;//分子泵
    QString vacuumGaugeOnOff;//高真空规
    QString frontValveOnOff;//前级阀
    QString angleValveOnOff;//角阀
    QString ventValveOnOff;//放空阀
    QString turboVentOnOff;//分子泵放空阀
    QString collisionGas1OnOff;//碰撞气1开关
    double collisionGasHe;//碰撞气1
    QString collisionGas2OnOff;//碰撞气开关
    double collisionGasH2;//碰撞气2
    double samplingConeT;//采样锥温度
    QString lenGroupOnOff;//透镜组电压开关
    double extractionLen;//提取透镜
    double hexapole;//六级杆
    double len1;//透镜1
    double len2;//透镜2
    double len3;//透镜3
    double focusingLen;//聚焦透镜
    double deflectionLen1;//偏转透镜1
    double deflectionLen2;//偏转透镜2
    double deflectionLen3;//偏转透镜3
    double deflectionLen4;//偏转透镜4
    double quadrupole;//四级杆
    double analogDetector;//模拟检测器
    double digitalDetector;//计数检测器
    double standardResolution;//模拟检测器
    double highResolution;//计数检测器

    //add set
    double screeningV;//脉冲计数甄别电压
    double analogOffsetV;//模拟信号偏置电压设置（AMP_OFFSET）(单位：V)（默认）
    double gateOpen;//脉冲Gate保护模拟阈值设置（COUNTOFF_SET）(单位：V)(打开值)
    double gateClose;//脉冲Gate保护模拟迟滞阈值设置（REF_COUNTOFF）(单位：V)(关闭值)
    ////1Byte 分辨标志位：

    //add read
    int turboPumpSpeed;//分子泵1转速  0-60000（0转/分钟）
    double turboPumpCurrent;//分子泵1电流  （A）
    double turboPumpT;//分子泵1温度
    double conePress;//高真空规检测真空度（mbar）
    double chamberPress;//低真空规检测真空度（mbar）（锥真空）
    double directXR;//X方向电阻值
    double directYR;//Y方向电阻值
    double inBoxT;//机箱内测温
    double inTorchT;//炬室测温
    double exhaustSensor;//排气流量传感器（m/s）（小数）
    double atomizationP;//雾化器压力监测（mbar）（小数）
    double icpCurrent;//ICP源电流
    double icpT;//ICP源温度
    double icpPositive;//ICP源正向功率反馈
};

class WorkFlow
{
public:
    WorkFlow();

    QList<WorkStep>  GetWorkSteps(QString);
    QList<QString> GetFlowNames();
    void InsetFlow(QString name,QList<WorkStep>);
    void RemoveFlow(QString name);
    void InsetStep(QString name,int index,WorkStep step);
    void AddStep(QString name,WorkStep step);
    void RemoveStep(QString name,int index);
    void Replace(QString name,int index,WorkStep step);
    void Clear();
    bool IsExistFlow(QString);

    friend QDataStream & operator<< ( QDataStream & stream, const WorkFlow & workFlow )
    {
        stream<<workFlow.flows;
        return stream;
    }

    friend QDataStream &	operator>> ( QDataStream & stream, WorkFlow & workFlow  )
    {
        stream>>workFlow.flows;
        return stream;
    }

    QHash<QString,QList<WorkStep> > flows;
};

struct LimitValue
{
    double coolwarterUp;//4Byte：冷却水流量报警上限；（L/min）
    double coolwarterLow;
    double exhaustUp;//4Byte：排风上限（m/s）
    double exhaustLow;
    double interTempUp;//4Byte：仪器内部温度上限（oC）
    double InterTempLow;
    double rfPowerUp;//4Byte：RF功率上限(W)
    double rfPowerLow;
    double atomizationUp;//4Byte：雾化气流量上限（L/min）
    double atomizationLow;
    double auxiliaryUp;//4Byte：辅助气流量上限（L/min）
    double auxiliaryLow;
    double coolerUp;//4Byte：冷却气流量上限（L/min）
    double coolerLow;
    double referVoltUp;//4Byte：4.096V参考电压偏差上限(v)
    double referVoltLow;
};
#endif // ANALYTEDATABASE_H
